package it.unisalento.appsalento.activity.fragment;

import it.unisalento.R;
import it.unisalento.appsalento.Constants.Constants;
import it.unisalento.appsalento.activity.App;
import it.unisalento.appsalento.adapter.NewsAdapter;
import it.unisalento.appsalento.bo.mock.MockBo;
import it.unisalento.appsalento.model.Appello;
import it.unisalento.appsalento.model.GetNewsResponse;
import it.unisalento.appsalento.model.Notizia;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Dialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Fragment che contiene la lista delle news, il pulsante per accedere al
 * libretto, quello per accedere alla lista di appelli e quello per i risultati
 */
public class HomeFragment extends Fragment {
	/**
	 * numero di millisecondi che intercorrono tra un aggiornamenti delle news e
	 * il successivo impostato a 10 minuti
	 */
	private int NEWS_UPDATE_INTERVAL = 600000;

	private Button mLibrettoButton;
	private Button mAppelliButton;
	private ListView mNewsList;
	private TextView mEmptyList;
	private TextView mRisultati;
	private RelativeLayout mRisultatiButton;

	private NewsAdapter adapter;
	private ArrayList<Notizia> newsList = new ArrayList<Notizia>();

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		View rootView = inflater.inflate(R.layout.fragment_home, container,
				false);

		mLibrettoButton = (Button) rootView.findViewById(R.id.libretto_button);
		mAppelliButton = (Button) rootView.findViewById(R.id.appelli_button);
		mRisultati = (TextView) rootView.findViewById(R.id.risultati_button_number);
		mRisultatiButton = (RelativeLayout) rootView.findViewById(R.id.risultati_button_layout);
		
		refreshRisultatiButton();
		
		mLibrettoButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				FragmentManager fragmentManager = getFragmentManager();
				fragmentManager.beginTransaction()
						.replace(R.id.content_frame, new LibrettoFragment())
						.commit();
			}
		});
		mAppelliButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				FragmentManager fragmentManager = getFragmentManager();
				fragmentManager.beginTransaction()
						.replace(R.id.content_frame, new CalendarioFragment())
						.commit();
			}
		});
		
		mNewsList = (ListView) rootView.findViewById(R.id.news_list);
		mEmptyList = (TextView) rootView.findViewById(R.id.empty_news_list);

		adapter = new NewsAdapter(getActivity(), R.layout.news_list_item,
				newsList);
		mNewsList.setAdapter(adapter);
		mNewsList.setEmptyView(mEmptyList);

		LocalBroadcastManager
				.getInstance(getActivity().getApplicationContext())
				.registerReceiver(mUpdateNewsReceiver,
						new IntentFilter(Constants.UPDATE_NEWS_EVENT));

		new GetNewsTask().execute();

		mNewsList.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View v,
					int position, long id) {
				Notizia notizia = (Notizia) parent.getItemAtPosition(position);

				Dialog dialog = new Dialog(parent.getContext());
				dialog.setContentView(R.layout.news_dialog);
				dialog.setTitle(notizia.getTitolo());

				TextView mNotiziaData = (TextView) dialog
						.findViewById(R.id.notizia_data);
				TextView mNotiziaTesto = (TextView) dialog
						.findViewById(R.id.notizia_testo);

				mNotiziaData.setText(notizia.getData().toString());
				mNotiziaTesto.setText(notizia.getTesto());

				dialog.setCancelable(true);
				dialog.show();
			}
		});

		return rootView;
	}

	@Override
	public void onResume() {
		super.onResume();
		new GetNewsTask().execute();
	}
	
	public void refreshRisultatiButton() {
		int risultati = 0;
		for (Appello appello : App.appelli) {
			if (appello.getStato().equals(Appello.DA_ACCETTARE)
					|| appello.getStato().equals(Appello.RISULTATO_ACCETTATO)
					|| appello.getStato().equals(Appello.RISULTATO_RIFIUTATO)) {
				risultati ++;
			}
		}
		
		if (risultati == 0) {
			//TODO: grafica diversa per disabilitare il pulsante risultati
		} else {
			mRisultatiButton.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View view) {
					if (App.risultatiFragment==null){
						App.risultatiFragment = new RisultatiFragment();
					}
					FragmentManager fragmentManager = getFragmentManager();
					fragmentManager.beginTransaction()
							.replace(R.id.content_frame, App.risultatiFragment)
							.commit();
				}
			});
			if (risultati>0) {
				mRisultati.setVisibility(View.VISIBLE);
				mRisultati.setText(risultati+"");
			}
		}
	}

	/**
	 * Task per reperire le news
	 * 
	 */
	public class GetNewsTask extends AsyncTask<Void, Void, Boolean> {
		@Override
		protected Boolean doInBackground(Void... params) {
			JSONObject holder = new JSONObject();
			DefaultHttpClient httpclient = new DefaultHttpClient();
			HttpPost httpost = new HttpPost(Constants.URL_REST
					+ Constants.SERVICE_NEWS);
			try {
				setUtente(holder, httpclient, httpost);
				if ("".equals(App.utente.getMatricola())) {
					return false;
				}
			} catch (JSONException e) {
				e.printStackTrace();
				return false;
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				return false;
			} catch (ClientProtocolException e) {
				e.printStackTrace();
				return false;
			} catch (IOException e) {
				e.printStackTrace();
				return false;
			}

			return true;
		}

		/**
		 * Metodo che si occupa di recuperare e settare l'utente
		 * 
		 * @param holder
		 * @param httpclient
		 * @param httpost
		 * @throws JSONException
		 * @throws UnsupportedEncodingException
		 * @throws IOException
		 * @throws ClientProtocolException
		 * @throws JsonParseException
		 * @throws JsonMappingException
		 */
		private void setUtente(JSONObject holder, DefaultHttpClient httpclient,
				HttpPost httpost) throws JSONException,
				UnsupportedEncodingException, IOException,
				ClientProtocolException, JsonParseException,
				JsonMappingException {
			InputStream is = null;
			Intent intent;

			boolean loop = true;
			while (loop) {
				if (!Constants.MOCK_ENABLED) {
					holder.put(new String("username"), App.utente.getUsername());
					holder.put(new String("password"), App.utente.getPassword());
					StringEntity se = new StringEntity(holder.toString());

					httpost.setEntity(se);

					httpost.setHeader("Accept", "application/json");
					httpost.setHeader("Content-type", "application/json");
					HttpResponse response = httpclient.execute(httpost);
					HttpEntity httpEntity = response.getEntity();
					is = httpEntity.getContent();
				} else {
					is = getActivity().getAssets().open(
							MockBo.GET_NEWS_RESPONSE);
				}
				InputStreamReader isr = new InputStreamReader(is);
				StringBuilder sb = new StringBuilder();
				BufferedReader br = new BufferedReader(isr);
				String read = br.readLine();

				while (read != null) {
					sb.append(read);
					read = br.readLine();

				}

				intent = new Intent(Constants.UPDATE_NEWS_EVENT);
//				String sbstring = sb.toString();
				intent.putExtra(Constants.RESPONSE_NEW_EXTRA_NAME, sb.toString());
				LocalBroadcastManager.getInstance(
						getActivity().getApplicationContext()).sendBroadcast(
						intent);

				try {
					Thread.sleep(NEWS_UPDATE_INTERVAL);
				} catch (InterruptedException e) {
					e.printStackTrace();
//					return;
				}
			}
		}
	}

	private BroadcastReceiver mUpdateNewsReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {
			try {
				GetNewsResponse response = new ObjectMapper().readValue(
						intent.getStringExtra(Constants.RESPONSE_NEW_EXTRA_NAME),
						GetNewsResponse.class);

				if (response.isOk()) {
					newsList.clear();
					newsList.addAll(response.getNews());
					adapter.notifyDataSetChanged();
				}
			} catch (JsonParseException e) {
				e.printStackTrace();
				return;
			} catch (JsonMappingException e) {
				e.printStackTrace();
				return;
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
	};
}
